/*
 * 
 */
package com.yuanmei.stockeyes.charts;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import com.tictactec.ta.lib.Core;
import com.tictactec.ta.lib.MAType;
import com.tictactec.ta.lib.MInteger;
import com.tictactec.ta.lib.RetCode;
import com.tictactec.ta.lib.meta.annotation.IntegerList;
import com.yuanmei.stockeyes.R;

import android.content.Context;
import android.graphics.PointF;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.view.View;
import android.view.View.OnTouchListener;

import cn.limc.androidcharts.view.MACDChart;
import cn.limc.androidcharts.entity.IStickEntity;
import cn.limc.androidcharts.entity.ListChartData;
import cn.limc.androidcharts.entity.MACDEntity;
import cn.limc.androidcharts.event.IDisplayCursorListener;

public class TalibMacdChart implements ITalibChart {

    private final Core mTaLibCore = new Core();
    private MACDChart mMacdChartView;
    private static final String TAG = TalibMacdChart.class.getName();

    private int mMacdFastPeriod   = 12;
    private int mMacdSlowPeriod   = 26;
    private int mMacdSignalPeriod = 9;

    private String mMacdFastPeriodName;
    private String mMacdSlowPeriodName;
    private String mMacdSignalPeriodName;

    private Context mContext;

    private List<IStickEntity> mMacdEntityList;
    private int                mTaIdxDataSetsBegin;
    private int                mTaIdxDataSetsNumber;

    public TalibMacdChart(Context context) {
        mMacdChartView = new MACDChart(context);
        TalibChartFactory.commonInitGridChart(mMacdChartView);
        TalibChartFactory.commonInitSlipStickChart(mMacdChartView);
        mMacdChartView.setMacdDisplayType(MACDChart.MACD_DISPLAY_TYPE_STICK);
        mContext =  mMacdChartView.getContext();

        mMacdFastPeriodName   = mContext.getString(R.string.param_fast_period);
        mMacdSlowPeriodName   = mContext.getString(R.string.param_slow_period);
        mMacdSignalPeriodName = mContext.getString(R.string.param_dif_ma_period);
    }

    @Override
    public List<Map<String, Object>> getTaParamsList() {

        List<Map<String, Object>> outParamsList = new ArrayList<Map<String, Object>>();
        Map<String, Object> item = new HashMap<String, Object>();
        item.put(ITalibChart.ITaParamNameKey,  mMacdFastPeriodName);
        item.put(ITalibChart.ITaParamValueKey, mMacdFastPeriod);
        outParamsList.add(item);

        item = new HashMap<String, Object>();
        item.put(ITalibChart.ITaParamNameKey,  mMacdSlowPeriodName);
        item.put(ITalibChart.ITaParamValueKey, mMacdSlowPeriod);
        outParamsList.add(item);

        item = new HashMap<String, Object>();
        item.put(ITalibChart.ITaParamNameKey,  mMacdSignalPeriodName);
        item.put(ITalibChart.ITaParamValueKey, mMacdSignalPeriod);
        outParamsList.add(item);

        return outParamsList;
    }

    @Override
    public void setTaParams(Hashtable<String, Integer> inParamMap) {


         if (inParamMap.containsKey(mMacdFastPeriodName)
                 && inParamMap.containsKey(mMacdSlowPeriodName)
                 && inParamMap.containsKey(mMacdSignalPeriodName)
                 ) {
             mMacdFastPeriod = inParamMap.get(mMacdFastPeriodName);
             mMacdSlowPeriod = inParamMap.get(mMacdSlowPeriodName);
             mMacdSignalPeriod = inParamMap.get(mMacdSignalPeriodName);
         }
    }

    @Override
    public boolean reloadData(int dataLen,
                              float[] openPrices,
                              float[] highPrices,
                              float[] lowPrices,
                              float[] closePrices,
                              float[] volumes,
                              float[] amounts,
                              int[] dates) {
        MInteger outBegIdx    = new MInteger();
        MInteger outNBElement = new MInteger();
        double[] outDif       = new double[dataLen];
        double[] outDea       = new double[dataLen];
        double[] outMacdHist  = new double[dataLen];
        MAType matype = MAType.Dema;
        RetCode retCode = mTaLibCore.macdExt(0, closePrices.length - 1, closePrices,
                mMacdFastPeriod, matype, mMacdSlowPeriod, matype, mMacdSignalPeriod, matype,
                outBegIdx, outNBElement, outDif, outDea, outMacdHist);
        if (retCode != RetCode.Success) {
            Log.e(TAG, "buildMACDChart mTaLibCore.macd calc error retCode="
                    + retCode);
            return false;
        }
//        Log.i(TAG, "DBG MACDChart outBegIdx=" + outBegIdx.value + ", outNBElement=" + outNBElement.value);
        List<IStickEntity> macd = new ArrayList<>();
        for (int i = 0; i < dataLen; i++) {
            if (i < outBegIdx.value) {
                macd.add(new MACDEntity(outDea[0], outDif[0], outMacdHist[0],
                        dates[i]));
            } else if ((i >= outBegIdx.value)
                    && (i < (outBegIdx.value + outNBElement.value))) {
                int idx = i - outBegIdx.value;
                macd.add(new MACDEntity(outDea[idx], outDif[idx],
                        outMacdHist[idx], dates[i]));
            }
        }

        // MACD special style
        //mMacdChartView.setMacdDisplayType(MACDChart.MACD_DISPLAY_TYPE_LINE_STICK);

        mMacdChartView.setStickData(new ListChartData<>(macd));

        mMacdEntityList      = macd;
        mTaIdxDataSetsBegin  = outBegIdx.value;
        mTaIdxDataSetsNumber = outNBElement.value;
        return true;
    }

    @Override
    public int getTaIndexNumber() {
        return mTaIdxDataSetsNumber;
    }

    @Override
    public String getTaIndexShortName() {
        return "MACD";
    }

    @Override
    public String getTaIndexParms() {
        return  mMacdFastPeriod
                + "," + mMacdSlowPeriod
                + "," + mMacdSignalPeriod;
    }
    @Override
    public Spanned getTaIndexDetail() {
        if (null == mMacdEntityList) {
            return new SpannableString("----");
        }
        int index = mMacdChartView.getSelectedIndex();

        MACDEntity entity   = (MACDEntity) mMacdEntityList.get(index);
        String     deaText  = String.format(Locale.ENGLISH, "DEA:%.2f ", entity.getDea());
        String     diffText = String.format(Locale.ENGLISH, "DIF:%.2f ", entity.getDiff());
        String     macdText = String.format(Locale.ENGLISH, "MACD:%.2f ", entity.getMacd());

        String    finalString = deaText + diffText + macdText;
        Spannable sb          = new SpannableString(finalString);

        sb.setSpan(new ForegroundColorSpan(mMacdChartView.getDeaLineColor()), finalString.indexOf(deaText),
                finalString.indexOf(deaText) + deaText.length(), Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
        sb.setSpan(new ForegroundColorSpan(mMacdChartView.getDiffLineColor()), finalString.indexOf(diffText),
                finalString.indexOf(diffText) + diffText.length(), Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
        if (entity.getMacd() > 0.0) {
            sb.setSpan(new ForegroundColorSpan(mMacdChartView.getPositiveStickColor()), finalString.indexOf(macdText),
                    finalString.indexOf(macdText) + macdText.length(), Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
        } else {
            sb.setSpan(new ForegroundColorSpan(mMacdChartView.getNegativeStickColor()), finalString.indexOf(macdText),
                    finalString.indexOf(macdText) + macdText.length(), Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
        }
//        sb.setSpan(new ForegroundColorSpan(Color.GRAY), finalString.indexOf(dateText),
//                finalString.indexOf(dateText) + dateText.length(), Spanned.SPAN_EXCLUSIVE_INCLUSIVE);

        return (sb);
    }

    @Override
    public int getTaIndexBegin() {
        return mTaIdxDataSetsBegin;
    }

    @Override
    public View getChartView() {
        return mMacdChartView;
    }

    @Override
    public void setDisplayFrom(int from) {
        mMacdChartView.setDisplayFrom(from);
    }

    @Override
    public void setDisplayCrossXOnTouch(boolean displayCrossXOnTouch) {
        mMacdChartView.setDisplayCrossXOnTouch(displayCrossXOnTouch);
    }

    @Override
    public void setDisplayNumber(int number) {
        mMacdChartView.setDisplayNumber(number);
    }

    @Override
    public void setOnTouchListener(OnTouchListener l) {
        mMacdChartView.setOnTouchListener(l);
    }

    @Override
    public void setOnDisplayCursorListener(
            IDisplayCursorListener l) {
        mMacdChartView.setOnDisplayCursorListener(l);
    }

    @Override
    public PointF getTouchPoint() {
        return mMacdChartView.getTouchPoint();
    }

    @Override
    public void setTouchPoint(PointF touchPoint) {
        mMacdChartView.setTouchPoint(touchPoint);
    }

    @Override
    public void postInvalidate() {
        mMacdChartView.postInvalidate();
    }

    @Override
    public float getValidMiddleY() {
        return mMacdChartView.getValidMiddleY();
    }
}
